package org.example.service;

import org.example.beans.SingletonBean;
import org.example.beans.PrototypeBean;
import org.example.beans.ThreadScopeBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.stereotype.Service;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;

/**
 * 作用域测试服务
 * 用于演示不同作用域Bean的行为
 */
@Service
public class ScopeTestService {
    
    @Autowired
    private ApplicationContext applicationContext;
    
    @Autowired
    private SingletonBean singletonBean;
    
    /**
     * 测试Singleton作用域
     * Singleton Bean在整个容器中只有一个实例
     */
    public void testSingletonScope() {
        System.out.println("\n=== 测试Singleton作用域 ===");
        
        // 多次获取同一个Bean，应该是同一个实例
        SingletonBean bean1 = applicationContext.getBean(SingletonBean.class);
        SingletonBean bean2 = applicationContext.getBean(SingletonBean.class);
        SingletonBean bean3 = singletonBean; // 通过注入获取
        
        System.out.println("Bean1 ID: " + bean1.getInstanceId());
        System.out.println("Bean2 ID: " + bean2.getInstanceId());
        System.out.println("Bean3 ID: " + bean3.getInstanceId());
        
        System.out.println("Bean1 == Bean2: " + (bean1 == bean2));
        System.out.println("Bean1 == Bean3: " + (bean1 == bean3));
        System.out.println("Bean2 == Bean3: " + (bean2 == bean3));
        
        bean1.doSomething();
    }
    
    /**
     * 测试Prototype作用域
     * Prototype Bean每次请求都会创建新实例
     */
    public void testPrototypeScope() {
        System.out.println("\n=== 测试Prototype作用域 ===");
        
        // 多次获取Bean，每次都应该是新实例
        PrototypeBean bean1 = applicationContext.getBean(PrototypeBean.class);
        PrototypeBean bean2 = applicationContext.getBean(PrototypeBean.class);
        PrototypeBean bean3 = applicationContext.getBean(PrototypeBean.class);
        
        System.out.println("Bean1 ID: " + bean1.getInstanceId());
        System.out.println("Bean2 ID: " + bean2.getInstanceId());
        System.out.println("Bean3 ID: " + bean3.getInstanceId());
        
        System.out.println("Bean1 == Bean2: " + (bean1 == bean2));
        System.out.println("Bean1 == Bean3: " + (bean1 == bean3));
        System.out.println("Bean2 == Bean3: " + (bean2 == bean3));
        
        bean1.doSomething();
        bean2.doSomething();
        bean3.doSomething();
    }
    
    /**
     * 测试自定义ThreadLocal作用域
     * ThreadLocal Bean在每个线程中只有一个实例
     */
    public void testThreadScope() {
        System.out.println("\n=== 测试ThreadLocal作用域 ===");
        
        ExecutorService executor = Executors.newFixedThreadPool(3);
        
        for (int i = 0; i < 3; i++) {
            final int threadNum = i + 1;
            executor.submit(() -> {
                try {
                    // 在同一线程中多次获取Bean，应该是同一个实例
                    ThreadScopeBean bean1 = applicationContext.getBean(ThreadScopeBean.class);
                    ThreadScopeBean bean2 = applicationContext.getBean(ThreadScopeBean.class);
                    
                    System.out.println("线程" + threadNum + " - Bean1 ID: " + bean1.getInstanceId());
                    System.out.println("线程" + threadNum + " - Bean2 ID: " + bean2.getInstanceId());
                    System.out.println("线程" + threadNum + " - Bean1 == Bean2: " + (bean1 == bean2));
                    
                    bean1.doSomething();
                    
                    // 模拟一些工作
                    Thread.sleep(100);
                } catch (InterruptedException e) {
                    Thread.currentThread().interrupt();
                }
            });
        }
        
        executor.shutdown();
        try {
            executor.awaitTermination(5, TimeUnit.SECONDS);
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
        }
    }
    
    /**
     * 显示所有已注册的Bean信息
     */
    public void showBeanInfo() {
        System.out.println("\n=== Spring容器中的Bean信息 ===");
        String[] beanNames = applicationContext.getBeanDefinitionNames();
        for (String beanName : beanNames) {
            if (beanName.contains("Bean") || beanName.contains("Service")) {
                System.out.println("Bean名称: " + beanName + 
                                 ", 类型: " + applicationContext.getType(beanName));
            }
        }
    }
} 